/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#ifndef GIMI_MESSAGE_H
#define GIMI_MESSAGE_H

#include "gimiutils.h"

namespace gimi
{
  
  /** Container class of arrived message for easy use.
   *
   * This class encapsulates data received with GIMI to one container
   * containing all data and addressing information.
   */
  class GIMIMessage
  {
  public:
    /** Default constructor.
     */
    GIMIMessage();
    

    /** Destructor.
     */
    virtual ~GIMIMessage();
    

    /** Assign data by giving pointer and data length.
     *
     * @param[in] sourceData    Pointer to sourcedata
     * @param[in] sourceDataLen Length of data to set.
     */
    void setData(const char *sourceData,
                 const int sourceDataLen);
    

    /** Get Major type ID.
     * 
     * @return                  Currently assigned Major type ID.
     */
    int getMajorTypeId(void) const;


    /** Get Minor type ID.
     * 
     * @return                  Currently assigned Minor type ID.
     */
    int getMinorTypeId(void) const;


    /** Get messageID.
     * 
     * @return                  Currently assigned messageID.
     */
    int getMessageId(void) const;


    /** Get Sender ID.
     * 
     * @return                  Currently assigned Sender ID.
     */
    int getSenderId(void) const;


    /** Get Message flags.
     * 
     * @return                  Currently assigned message flags.
     */
    int getMessageFlags(void) const;


    /** Get message payload size.
     * 
     * @return                  Currently assigned payload size.
     */
    int getDatalength(void) const;


    /** Get pointer to data inside container.
     * 
     * \todo This should probably be 'const char *', but as it is very
     * widely used in current form, changing it requires recompiling
     * all dependent components.
     *
     * @return                  Pointer to data.
     */
    char *getData(void) const;


    /** Is this message a status message?
     * 
     * @return                  'true' if this is a status message, otherwise 'false'.
     */
    bool isStatusMessage(void) const;

    
    /** Reset message.
     *
     * Empties this message. Deletes *data.
     *
     */
    virtual void reset(void);


    /** Move given GIMIMessage to current, and invalidate the original.
     *
     * \note The given GIMIMessage is invalidated, hence it doesn't
     * contain the original data anymore.
     *
     * \param[in] msg           Message to assign to this message.
     */
    virtual void assign(GIMIMessage &msg);

    
    /**
     * Copies given GIMIMessage to current.
     *
     * @param[in] msg           Source message to copy from.
     */
    virtual void copy(GIMIMessage &msg);


    gim::time arrivalTime; ///< Contains time of arrival of a message

    bool statusMessage;    ///< Tells if this is a statusmessage from hub, or
                           ///< just a normal message

    int majorTypeId;       ///< Message type (aka. protocol magic number)
    int minorTypeId;       ///< (device number identifier etc.)
    int messageId;         ///< Id-number of message, 0 if not defined explicitly.
    int senderId;          ///< Message sender
    int messageFlags;      ///< Flags from message.
    int datalength;        ///< Length of data in message.
    char *data;            ///< Pointer to message data.

  private:
    // Prevents use of copy constructors
    GIMIMessage(const GIMIMessage& gimiMessage);
    const GIMIMessage& operator= (const GIMIMessage& right);
  };

} // end namespace gimi

#endif // GIMI_MESSAGE_H

